home *** CD-ROM | disk | FTP | other *** search
/ Just Call Me Internet / Just Call Me Internet.iso / prog / atari / m2 / cat3src / magic / d / xbra.d < prev   
Text File  |  1997-10-26  |  9KB  |  217 lines

  1. DEFINITION MODULE XBRA;
  2.  
  3. (*------------------------------------------------------------------------*
  4.  * Universelle XBRA-Funktionen                  Version 1.1  vom  18.6.89
  5.  *
  6.  * Erstellt von Thomas Tempelmann.
  7.  *
  8.  * Die vorliegende Version ist unter dem Megamax Modula-2-System compilierbar,
  9.  * fr H„nisch- und SPC-Modula sind nur wenige Anpassungen n”tig.
  10.  *
  11.  * Die vorhandenen Funktionen bieten alles, um auf einfache Weise installierte
  12.  * Vektoren zu erkunden (wahlweise alle oder einen spezifischen) und sie
  13.  * korrekt ein-, bzw. wieder auszutragen.
  14.  *
  15.  * Wurde eine Funktion installiert, kann durch die Funktion 'PreviousEntry' die
  16.  * vorher installierte Routine ermittelt werden. Damit ist es dann m”glich,
  17.  * den Vorg„nger in der Funktion selbst aufzurufen, falls dies n”tig w„re.
  18.  * Die zum Aufrufen notwendigen Funktionen sind jedoch nicht Bestandteil
  19.  * dieser XBRA-Library, da sie erstens Compiler-spezifisch und zweitens
  20.  * sie je nach Anwendung sehr unterschiedlich implementiert werden mssen.
  21.  *
  22.  * Die Funktionen sind so ausgelegt, daž sie normalerweise im User-Mode
  23.  * aufgerufen werden und selbst beim Zugriff ber die Vektoren in den Super-
  24.  * visor-Mode wechseln (das Programm darf sich aber auch bereits im Supervi-
  25.  * sor-Mode befinden). Dies erleichtert dem Programmierer die Anwendung der
  26.  * Funktionen. Da die Anwendungen beim Installieren von Vektoren in der Regel
  27.  * nicht zeitkritisch ausgelegt sein brauchen, sollte man diese Komfortabilit„t
  28.  * dem leichten Zeitverlust durch - meist - zwei statt nur einem Wechsel vom
  29.  * User- in den Supervisor-Mode vorziehen.
  30.  *
  31.  *
  32.  * Hier noch eine allgemeine Beschreibung zur Anwendung der Funktionen:
  33.  *
  34.  * Folgendermažen sieht eine XBRA-Installation aus:
  35.  *
  36.  *   vector:= 400H;   (# z.B. der 'etv_timer'-Vektor #)
  37.  *   IF NOT Installed ('Test', vector, at) THEN
  38.  *     Create (carrier, 'Test', ADDRESS (TestProzedur), entry);
  39.  *     Install (entry, at)
  40.  *   END;
  41.  *
  42.  * 'Installed' prft, ob die Funktion schon mit XBRA-Kennung installiert
  43.  * ist. Wenn nicht, wird mit 'Create' ein XBRA-Header erzeugt, der neben
  44.  * der XBRA-Informationen auch eine Sprunganweisung enth„lt. Der so
  45.  * erzeugte Header wird dann mit 'Install' als erster neuer Vektor
  46.  * eingetragen und die XBRA-Verkettung erzeugt.
  47.  *
  48.  * Da je nach Implementation verschiedene Prozeduren mit beliebigen
  49.  * Parametern verwendet werden k”nnten, und der XBRA-Header nur einfach
  50.  * dazwischengesetzt wird, ist die Prozeduradresse 'call' als ADDRESS
  51.  * deklariert. Fr die korrekte Parameterbergabe haben nicht die XBRA-
  52.  * Funktionen zu sorgen, sondern schon die Routine, die zu installierende
  53.  * Funktion ber den Vektor aufruft.
  54.  *
  55.  * Zum Vergleich obige Installation ohne XBRA:
  56.  *   vector:= 400H;  (# VAR vector: POINTER TO ADDRESS #)
  57.  *   vector^:= ADDRESS (TestProzedur);
  58.  * Falls es Probleme gibt, sollte erst das Programm ohne XBRA zum Laufen
  59.  * gebracht werden, und dann erst die XBRA-Installation eingefgt werden.
  60.  * Z.B. ist beim Megamax-System zu beachten, daž normalerweise Installationen
  61.  * ber externe Vektoren ber die Funktionen aus dem Modul 'Calls' vorgenommen
  62.  * werden sollten. Dies bleibt auch so, wenn dann die XBRA-Funktionen zuhilfe
  63.  * genommen werden!
  64.  *
  65.  * Soll die Funktion sp„ter wieder aus der Vektor-Kette ausgeh„ngt werden,
  66.  * geht das so:
  67.  *
  68.  *   IF Installed ('Test', vector, at) THEN
  69.  *     Remove (at)
  70.  *   END
  71.  *
  72.  * Bei 'PreviousEntry' (s.o.) wird der bei 'Create' erhaltene 'entry'-Wert
  73.  * wieder bergeben, um z.B. in 'TestProzedur' den Vorg„nger zu
  74.  * ermitteln und dann ggf. aufzurufen.
  75.  *
  76.  * 'Query' dient dazu, alle installierten XBRA-Kennungen einer Vektor-
  77.  * Kette zu ermitteln. Dabei k”nnen auch z.B. mit folgender Routine alle
  78.  * installierten XBRA-Vektoren ausgeh„ngt werden:
  79.  *
  80.  *   PROCEDURE step (at: ADDRESS; name: Str4): BOOLEAN;
  81.  *     BEGIN
  82.  *       (#
  83.  *        * Hier k”nnten der jeweilige Vorg„nger mit
  84.  *        *  'PreviousEntry ( Entry (at) )'
  85.  *        * oder die Adr. der aufgerufenen Prozedur mit
  86.  *        *  'Called (at)'  ermittelt und angezeigt werden.
  87.  *        #)
  88.  *       IF prev # NIL THEN (# ist dies ein XBRA-Eintrag? #)
  89.  *         Remove (at)      (#  -> nur dann kann er entfernt werden #)
  90.  *       END;
  91.  *       RETURN TRUE        (# weitermachen, solange die Kette weitergeht #)
  92.  *     END step;
  93.  *
  94.  *   PROCEDURE RemoveAll (vector: ADDRESS);
  95.  *     BEGIN Query (vector, step) END RemoveAll;
  96.  *
  97.  *
  98.  * HINWEIS:
  99.  * --------
  100.  * Das Modul wurde auf Implementationsebene so ge„ndert, daž es ohne
  101.  * Žnderung auf allen Compilern lauff„hig ist.
  102.  *)
  103.  
  104. FROM SYSTEM IMPORT ADDRESS;
  105. FROM MagicSys IMPORT sCARDINAL;
  106.  
  107. TYPE
  108.  
  109.   ID = ARRAY [0..3] OF CHAR;            (* String zur Aufnahme der Kennung *)
  110.  
  111.   JmpCarrier = RECORD                   (* Interne Datenstruktur!     *)
  112.                  jmpInstr: sCARDINAL;   (*  - nicht darauf zugreifen! *)
  113.                  operand: ADDRESS
  114.                END;
  115.  
  116.   Carrier = RECORD      (* Interne Datenstruktur - nicht darauf zugreifen! *)
  117.               magic: ID;                (* CONST 'XBRA' *)
  118.               name : ID;                (* individuelle Kennung *)
  119.               prev : ADDRESS;           (* voriger Vektor *)
  120.               entry: JmpCarrier;
  121.             END;
  122.  
  123.   QueryProc = PROCEDURE ( (* at  : *) ADDRESS,
  124.                           (* name: *) ID      ): (* continue: *) BOOLEAN;
  125.  
  126.  
  127. (*
  128.  * Funktionen fr die XBRA-Installation
  129.  * ------------------------------------
  130.  *)
  131.  
  132. PROCEDURE Create (VAR use: Carrier; name: ID; call: ADDRESS;
  133.                   VAR entry: ADDRESS);
  134.   (*
  135.    * Erzeugt einen XBRA-Header mit einer Sprunganweisung zur Prozedur 'call'.
  136.    * Achtung: die Carrier-Variable muž global (statisch) deklariert sein -
  137.    *   sie muž so lange erhalten bleiben, wie die XBRA-Einbindung besteht!
  138.    * Der erhaltene 'entry'-Wert kann daraufhin mittels der Prozedur 'Install'
  139.    * in den gewnschten Vektor eingetragen werden.
  140.    *)
  141.  
  142. PROCEDURE Installed (name: ID; vector: ADDRESS; VAR at: ADDRESS): BOOLEAN;
  143.   (*
  144.    * Wird 'name' in Kette ab 'vector' gefunden, enth„lt 'at' die Adresse
  145.    * des Vektors auf den Funktionseinsprung (welcher Teil von 'Carrier' ist).
  146.    * Wird 'name' nicht gefunden, ist 'at'=vector
  147.    *)
  148.  
  149. PROCEDURE Install (entry: ADDRESS; at: ADDRESS);
  150.   (*
  151.    * Fgt einen XBRA-Header 'entry' im Vektor 'at' ein. Der alte Vektorinhalt
  152.    * wird im XBRA-Header gesichert und kann mittels 'PreviousEntry' abgefragt
  153.    * werden.
  154.    *)
  155.  
  156. PROCEDURE Remove (at: ADDRESS);
  157.   (*
  158.    * Klinkt den XBRA-Header, auf den der Vektor bei 'at' zeigt, aus.
  159.    * In den Vektor wird wieder der Vorg„nger eingetragen.
  160.    *)
  161.  
  162. (*
  163.  * Funktionen zum Abfragen XBRA-Informationen
  164.  * ------------------------------------------
  165.  *)
  166.  
  167. PROCEDURE Query (vector: ADDRESS; with: QueryProc);
  168.   (*
  169.    * Ruft 'with' fr alle im Vektor 'vector' installierten Funktionen auf,
  170.    * solange sie durch XBRA-Strukturen verbunden sind.
  171.    * Die 'with'-Funktion kann 'FALSE' zurckgeben, um die Aufrufe vorzeitig
  172.    * zu beenden.
  173.    *)
  174.  
  175. PROCEDURE Entry (at: ADDRESS): ADDRESS;
  176.   (*
  177.    * Liefert die Adresse, auf die der Vektor 'at' zeigt.
  178.    * Dies ist der "Entry", vor dem ggf. die XBRA-Struktur steht.
  179.    * Das Ergebnis dieser Funktion kann z.B. fr die 'PreviousEntry'-Funktion
  180.    * verwendet werden, sollte jedoch nicht zur rein informativen Ermitttelung
  181.    * der in 'at' installierten Funktion verwendet werden - dafr ist 'Called'
  182.    * (s.u.) vorgesehen!
  183.    *)
  184.  
  185. PROCEDURE PreviousEntry (entry: ADDRESS): ADDRESS;
  186.   (*
  187.    * Liefert den "Entry", der vor dem angegebenen "Entry" installiert ist.
  188.    * Diese Funktion kann z.B. in der eigenen installierten Funktion dazu
  189.    * benutzt werden, den Vorg„nger aufzurufen (hier sollte aus Effizienz-
  190.    * grnden nicht 'Called' verwendet werden), um eine Aufrufkette zu reali-
  191.    * sieren (ist z.B. beim 200Hz-Vektor sinnvoll, da hier mehrere Routinen
  192.    * hintereinander installiert werden, die alle sich nacheinander aufrufen).
  193.    * Zu diesem Zweck muž dann der bei 'Create' erhaltene 'entry'-Wert ber-
  194.    * geben werden. Achtung: Da damit gerechnet werden muž, daž w„hrend der
  195.    * Lebzeit des Programms im Speicher die XBRA-Verkettung jederzeit ver-
  196.    * „ndert werden kann, darf nicht einmalig fest die Vorg„ngeradr. abgefragt
  197.    * und dann ber eine Programmlokale Variable adressiert werden, sondern
  198.    * muž immer genau dann, wenn sie ben”tigt wird, mit dieser Funktion ab-
  199.    * gefragt werden. Es sind dabei keine nennenswerten Zeitverluste zu be-
  200.    * frchten.
  201.    * Wenn 'entry'=NIL, oder kein Vorg„nger ermittelt werden kann (keine XBRA-
  202.    * Struktur vorhanden), wird NIL geliefert.
  203.    *)
  204.  
  205. PROCEDURE Called (at: ADDRESS): ADDRESS;
  206.   (*
  207.    * Liefert die korrekte Programmeinsprungstelle, die ber den Vektor 'at'
  208.    * erreicht wird. Dies w„re normalerweise identisch mit dem Ergebnis der
  209.    * 'Entry'-Funktion, jedoch wird hier erkannt, wenn diese "Entry"-Stelle
  210.    * nur die von diesem Modul erzeugte Sprunganweisung in die eigentliche
  211.    * Funktion ist, die bei der 'Install'-Funktion angegeben wurde. Dann
  212.    * wird jene Funktionsadresse geliefert.
  213.    *)
  214.  
  215. END XBRA.
  216.  
  217.